/**
 * 
 */
package hu.cubussapiens.client.core.login;

import hu.cubussapiens.client.core.Activator;

import java.io.IOException;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

/**
 * @author balage
 *
 */
public class AppManager {

//	private static AppManager instance = null;
	
	public static AppManager init(String host, String user, String pw){
		AppManager am = new AppManager(host);
		boolean succ = am.login(user, pw);
		if (succ){
			return am;
		}
		return null;
	}
	
//	public static AppManager getInstance(){
//		return instance;
//	}
	
	public static final String clientlogin = "https://www.google.com/accounts/ClientLogin";
	
	private final String approot;
	
	public String getApproot() {
		return approot;
	}
	
	public AppManager(String approot) {
		approot = approot.trim();
		if (!approot.endsWith("/"))
			approot += "/";
		this.approot = approot;
	}
	
	protected String getAuthKey(String email, String password) throws LoginException{
		HttpClient client = new HttpClient();
		PostMethod login = new PostMethod(clientlogin.toString());
		login.setParameter("Email", email);
		login.setParameter("Passwd", password);
		login.setParameter("source", "cubussapiens-client-0.0");
		login.setParameter("accountType", "HOSTED_OR_GOOGLE");
		login.setParameter("service", "ah");
		
		int result = -1;
		try {
			result = client.executeMethod(login);
		} catch (HttpException e) {
			login.releaseConnection();
			throw new LoginException(e,-1);
		} catch (IOException e) {
			login.releaseConnection();
			throw new LoginException(e, -1);
		}
        
		if (result != 200){
			login.releaseConnection();
			throw new LoginException(result);
		}
		
        
        String[] data;
		try {
			data = login.getResponseBodyAsString().split("\n");
		} catch (IOException e) {
			login.releaseConnection();
			throw new LoginException(e,-1);
		}
        String auth = "";
        for(String s : data){
        	s = s.trim();
        	if (s.startsWith("Auth="))
        		auth = s.substring(5);
        }
        
        if ("".equals(auth)){
        	login.releaseConnection();
        	throw new LoginException("No authorization code got",-1);
        }
        
        login.releaseConnection();
        
		return auth;
	}
	
	protected Cookie getCookie(String auth) throws LoginException{
		HttpClient client = new HttpClient();
		client.setState(new HttpState());
		GetMethod getcookie = new GetMethod(approot+"_ah/login");
        getcookie.setQueryString(new NameValuePair[]{
        		//new NameValuePair("continue","http://localhost/"),
        		new NameValuePair("continue",approot),
        		new NameValuePair("auth", auth)
        });
        
        getcookie.setFollowRedirects(false);
        try {
			client.executeMethod(getcookie);
		} catch (HttpException e) {
			getcookie.releaseConnection();
			throw new LoginException(e,-1);
		} catch (IOException e) {
			getcookie.releaseConnection();
			throw new LoginException(e,-1);
		}
		
		//System.out.println("Cookies:");
	    for(Cookie c : client.getState().getCookies()){
	    	if ("ACSID".equals(c.getName()))
	    		return c; 
	    }
	    
	    return null;
	}
	
	private Cookie cookie = null;
	
	public boolean isLoggedIn(){
		return cookie != null;
	}
	
	public boolean login(String email, String password){
		if (cookie != null)
			cookie = null;
		//	SessionSourceProvider.getInstance().disconnect();
		try {
			String authkey = getAuthKey(email, password);
			cookie = getCookie(authkey);
			return cookie != null;
		} catch (LoginException e) {
			Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Login failed!",e));
			return false;
		}
	}
	
	public void logout(){
		cookie = null;
	}
	
	public int execute(HttpMethod method) throws HttpException, IOException{
		HttpState state = new HttpState();
		if (cookie != null)
			state.addCookie(cookie);
		else
			System.err.println("Warning: No auth cookie!");
		HttpClient client = new HttpClient();
		client.setState(state);
		
		return client.executeMethod(method);
	}
	
}
